/**
 * Project:mail-settings-detector
 * File:MailSettingDetector.java
 * Copyright 2004-2014 Homolo Co., Ltd. All rights reserved.
 */
package com.homolo.msd;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * MailSettingDetector main class.
 *
 * @author rory
 */
public final class MailSettingDetector {

    /**
     * All the detectors in system.
     */
    private Set<Detector> detectors = new LinkedHashSet<Detector>();

    /**
     * The private default constructor for instance all of the Detectors.
     */
    private MailSettingDetector() {
        detectors.add(new ConfigFileDetector());
        detectors.add(new GuessDetector());
    }

    /**
     * @return the Singleton MailSettingDetector
     */
    public static MailSettingDetector getInstance() {
        return MailSettingDetectorHolder.instance;
    }

    /**
     *
     * Detect the email's MailSettings, detect by the Detectors order.
     *
     * @param mail the mail to detect
     * @return the MailSettings or null when can't detect
     * @throws IllegalArgumentException when the mail is not a valid email address
     */
    public MailSettings detect(String mail) {
        Pattern pattern = Pattern.compile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?");
        if (!pattern.matcher(mail).matches()) {
            throw new IllegalArgumentException(String.format("The mail[%s] is not valid", mail));
        }
        for (Detector detector : detectors) {
            MailSettings settings = detector.detect(mail);
            if (settings != null) {
                return settings;
            }
        }
        return null;
    }

    /**
     * The lazy Singleton Holder class.
     */
    private static class MailSettingDetectorHolder {

        /**
         * The Singleton instance.
         */
        private static MailSettingDetector instance = new MailSettingDetector();

        /**
         * The private constructor.
         */
        private MailSettingDetectorHolder () {
        }

    }

}
